package com.google.ma.rssreader;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;

import javax.xml.parsers.SAXParserFactory;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.GestureDetector;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.GestureDetector.OnDoubleTapListener;
import android.view.GestureDetector.OnGestureListener;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;

public class NewsListActivity extends Activity implements OnGestureListener, OnDoubleTapListener {

    private ProgressDialog progressDialog;

    private ArrayList<HashMap<String, String>> newsList;

    private ListView newsListView;

    private GestureDetector gestureDetector;

    private float[] textSize = { 18f, 22f };

    private Intent i;

    Handler refreshDataHandler = new Handler() {

        @SuppressWarnings("unchecked")
        public void handleMessage(Message msg) {

            newsList = (ArrayList<HashMap<String, String>>) msg.getData().getSerializable("newsList");
            if (progressDialog != null) {
                progressDialog.dismiss();
            }
            try {
                NewsItemAdapter adapter = new NewsItemAdapter(NewsListActivity.this, newsList, R.layout.news_item, new String[] { "title", "time", "description" }, new int[] { R.id.NewsTitleView,
                        R.id.NewsTimeView, R.id.NewsDescView });

                newsListView.setAdapter(adapter);
                newsListView.setOnItemLongClickListener(new OnItemLongClickListener() {

                    public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {

                        TextView newsDescView = (TextView) view.findViewById(R.id.NewsDescView);
                        float currentSize = newsDescView.getTextSize();

                        ScaleAnimation scaleAnimation = null;
                        if (Float.compare(currentSize, textSize[0]) == 0) {
                            newsDescView.setTextSize(textSize[1]);
                            scaleAnimation = new ScaleAnimation(1.2f, 1.2f, 1.2f, 1.2f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
                        } else if (Float.compare(currentSize, textSize[1]) == 0) {
                            newsDescView.setTextSize(textSize[0]);
                            scaleAnimation = new ScaleAnimation(0.8f, 0.8f, 0.8f, 0.8f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
                        }
                        if (scaleAnimation != null) {
                            scaleAnimation.setDuration(600);
                            view.setAnimation(scaleAnimation);
                            scaleAnimation.start();
                        }
                        return true;
                    }
                });
                newsListView.setOnItemClickListener(new OnItemClickListener() {

                    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                        String link = newsList.get(position).get("link");
                        Uri uri = Uri.parse(link);
                        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                        startActivity(intent);
                    }

                });
            } catch (RuntimeException e) {
                new AlertDialog.Builder(NewsListActivity.this).setMessage(e.getMessage()).show();
            }
        }
    };

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.news_list);

        gestureDetector = new GestureDetector(this);
        newsListView = (ListView) findViewById(R.id.NewsListView);

        progressDialog = ProgressDialog.show(this, getResources().getText(R.string.dialog_recdata), getResources().getText(R.string.dialog_recdatanow), true, false);

        i = getIntent();

        Thread loadDataThread = new Thread(new LoadDataHandler());
        loadDataThread.start();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        super.onCreateOptionsMenu(menu);
        menu.add(0, 1, 0, R.string.menu_smaller);
        menu.add(0, 2, 0, R.string.menu_larger);
        menu.add(0, 3, 0, R.string.menu_option);
        menu.add(0, 4, 1, R.string.menu_return);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        super.onOptionsItemSelected(item);
        switch (item.getItemId()) {
        case 1:
            int count = newsListView.getAdapter().getCount();
            for (int i = 0; i < count; i++) {
                View newsItemView = newsListView.getAdapter().getView(i, null, null);
                TextView newsDescView = (TextView) newsItemView.findViewById(R.id.NewsDescView);
                float currentSize = newsDescView.getTextSize();
                newsDescView.setTextSize(currentSize - 1);
            }
            break;
        case 2:
            // int count2 = newsListView.getAdapter().getCount();
            // for (int i = 0; i < count2; i++) {
            // LinearLayout itemLayout = (LinearLayout)
            // newsListView.getItemAtPosition(i);
            // TextView newsDescView = (TextView) itemLayout.getChildAt(2);
            // float currentSize = newsDescView.getTextSize();
            // newsDescView.setTextSize(currentSize + 1);
            // }
            break;
        case 4:
            finish();
            break;
        }
        return true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        return gestureDetector.onTouchEvent(event);
    }

    private ArrayList<HashMap<String, String>> rssParser(String url) {

        ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
        try {
            XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
            RssHandler rssHandler = new RssHandler();
            xmlReader.setContentHandler(rssHandler);
            xmlReader.parse(new InputSource(new StringReader(loadData(url))));
            list = rssHandler.getList();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("Parsing Error:" + e.getMessage());
        }
        return list;
    }

    private String loadData(String url) throws IOException, IllegalStateException {

        HttpClient httpClient = new DefaultHttpClient();
        HttpGet getMethod = new HttpGet(url);
        HttpResponse response = httpClient.execute(getMethod);

        StringBuilder dataBf = new StringBuilder();
        if (response != null) {
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String charset = "utf-8";
                Header contentType = entity.getContentType();
                if (contentType != null) {
                    String value = contentType.getValue();
                    int index = value.indexOf("charset=");
                    if (index != -1) {
                        charset = value.substring(index + 8);
                    }
                }

                InputStream in = entity.getContent();
                BufferedReader reader = new BufferedReader(new InputStreamReader(in, charset), 8192);

                String line = null;
                while ((line = reader.readLine()) != null) {
                    dataBf.append(line + "\n");
                }
                in.close();
            }
        }

        httpClient.getConnectionManager().shutdown();
        return dataBf.toString();

    }

    class LoadDataHandler implements Runnable {

        @Override
        public void run() {

            String url = NewsListActivity.this.i.getData().toString();
            newsList = rssParser(url);
            Message msg = new Message();
            Bundle bundle = new Bundle();
            bundle.putSerializable("newsList", newsList);
            msg.setData(bundle);
            refreshDataHandler.sendMessage(msg);
        }
    }

    @Override
    public boolean onDown(MotionEvent arg0) {

        return false;
    }

    @Override
    public boolean onFling(MotionEvent arg0, MotionEvent arg1, float arg2, float arg3) {

        return false;
    }

    @Override
    public void onLongPress(MotionEvent arg0) {

        TextView newsDescView = (TextView) findViewById(R.id.NewsDescView);
        float currentSize = newsDescView.getTextSize();
        if (Float.compare(currentSize, textSize[0]) == 0) {
            newsDescView.setTextSize(textSize[1]);
        } else if (Float.compare(currentSize, textSize[1]) == 0) {
            newsDescView.setTextSize(textSize[0]);
        }
    }

    @Override
    public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2, float arg3) {

        return false;
    }

    @Override
    public void onShowPress(MotionEvent arg0) {

    }

    @Override
    public boolean onSingleTapUp(MotionEvent arg0) {

        return false;
    }

    @Override
    public boolean onDoubleTap(MotionEvent arg0) {

        return false;
    }

    @Override
    public boolean onDoubleTapEvent(MotionEvent event) {

        return false;
    }

    @Override
    public boolean onSingleTapConfirmed(MotionEvent arg0) {

        return false;
    }
}